package com.zxy.supplier_system.server.repository

import com.zxy.supplier_system.server.entity.MarketAccount
import com.zxy.supplier_system.server.entity.MarketSaleDocument
import com.zxy.supplier_system.server.entity.MarketSaleDocumentItem
import com.zxy.supplier_system.server.entity.SystemService
import com.zxy.supplier_system.server.utils.joinOnce
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.domain.Specification
import org.springframework.data.jpa.repository.JpaRepository
import java.time.YearMonth

@Suppress("FunctionName")
interface MarketSaleDocumentItemRepository : JpaRepository<MarketSaleDocumentItem, MarketSaleDocumentItem.UnionId> {

    fun findAllByDocument_IdOrderBySequenceAsc(
        marketDocument_id: Long,
        pageable: Pageable
    ): Page<MarketSaleDocumentItem>

    fun existsByDocument_IdAndGoods_Id(marketDocument_id: Long, goods_id: Int): Boolean

    fun existsByDocument_IdAndGoods_Barcode(marketDocument_id: Long, goods_barcode: String): Boolean;

    fun findByDocument_Account_IdAndDocument_YearAndDocument_MonthAndGoods_IdAndGoods_SystemService(
        accountId: Int,
        year: Int,
        month: Int,
        goodsId: Int,
        systemService: SystemService
    ): MarketSaleDocumentItem?

    fun findAllByDocument_Account_IdAndDocument_YearAndDocument_MonthAndGoods_SystemService(
        accountId: Int,
        year: Int,
        month: Int,
        systemService: SystemService
    ): List<MarketSaleDocumentItem>

    fun deleteAllByDocument_Account_IdAndDocument_YearAndDocument_MonthAndDocument_Account_Market_SystemService(
        accountId: Int,
        year: Int,
        month: Int,
        market_systemService: SystemService
    )

    object Specifications {
        fun documentYearMonthGreaterThanOrEqualTo(yearMonth: YearMonth?): Specification<MarketSaleDocumentItem> {
            return Specification { root, _, criteriaBuilder ->
                yearMonth?.let {
                    val marketSaleDocumentJoin = root.joinOnce<MarketSaleDocumentItem, MarketSaleDocument>("document")
                    val yearField = marketSaleDocumentJoin.get<Int>("year")
                    criteriaBuilder.or(
                        criteriaBuilder.greaterThan(yearField, it.year),
                        criteriaBuilder.and(
                            criteriaBuilder.equal(yearField, it.year),
                            criteriaBuilder.greaterThanOrEqualTo(marketSaleDocumentJoin.get("month"), it.monthValue),
                        )
                    )
                }
            }
        }

        fun documentYearMonthLessThanOrEqualTo(yearMonth: YearMonth?): Specification<MarketSaleDocumentItem> {
            return Specification { root, _, criteriaBuilder ->
                yearMonth?.let {
                    val marketSaleDocumentJoin = root.joinOnce<MarketSaleDocumentItem, MarketSaleDocument>("document")
                    val yearField = marketSaleDocumentJoin.get<Int>("year")
                    criteriaBuilder.or(
                        criteriaBuilder.lessThan(yearField, it.year),
                        criteriaBuilder.and(
                            criteriaBuilder.equal(yearField, it.year),
                            criteriaBuilder.lessThanOrEqualTo(marketSaleDocumentJoin.get("month"), it.monthValue),
                        )
                    )
                }
            }
        }

        fun goodsBrandIn(brandIds: List<Int>): Specification<MarketSaleDocumentItem> {
            return GoodsRepository.Specifications.brandIn(brandIds) {
                it.joinOnce("goods")
            }
        }

        fun systemServiceEquals(systemService: SystemService):Specification<MarketSaleDocumentItem> {
            return SystemServiceRepository.Specifications.systemServiceEquals({ r->r.joinOnce<MarketSaleDocumentItem, MarketSaleDocument>("document").joinOnce<MarketSaleDocument, MarketAccount>("account").joinOnce("market")},systemService)
        }
    }

}
